path = "/gpfs/hpchome/a72094/rocket/projects/chromatin_to_splicing/"
library("dplyr")
library("readr")
library("devtools")
library("rtracklayer")
library("wiggleplotr")
library("GenomicRanges")
library('Rsamtools')
Loading required package: Biostrings
Loading required package: XVector
Attaching package: ‘Biostrings’
The following object is masked from ‘package:base’:
strsplit
library('tidyr')
Attaching package: ‘tidyr’
The following object is masked from ‘package:S4Vectors’:
expand
load_all("/gpfs/rocket/home/a72094/projects/chromatin_to_splicing/seqUtils/")
Loading seqUtils
Splaissimise andmed
#geenid, millel leidub splaiss QTL
splicing = read.table(paste0(path, "tabix/txrevise.significant.contained.sorted.txt.gz"))
#r2 seotud splass ja ca lookuste paarid
ca_splicing = read.table(paste0(path, "results/rsquared08/cqn_contained_rsq.txt"))
Kromatiini avatuse andmed
Aluseks peavad olema kromatiini avatuse kühmud, millel leidub: 1. statistiliselt oluline caQTL 25872 2. caQTL on seotud splaiss QTL’ga
Alustuseks leian kõik kühmud, mis vastavad kriteeriumitele
ca = read.table(paste0(path, 'tabix/cqn_permutations_100000_significant.sorted.txt.gz'))
ca_interesting_peaks = ca[which(ca$V8 %in% ca_splicing$V1),]
rm(ca)
interesting_peaks = dplyr::select(ca_interesting_peaks, c("V1", "V2", "V3", "V4", "V8", "V9", "V10", "V17","V19"))
colnames(interesting_peaks) = c("peak_id","peak_chr", "peak_start", "peak_end", "peak_snpid", "peak_snp_chr", "peak_snp_pos", "peak_slope", "ca_pvalue")
interesting_peaks
Geenid, mille splaissimine on R2 seotud kromatiini avatusega
interesting_genes = splicing[which(splicing$V10 %in% ca_splicing$V4),c("V1", "V2", "V3","V4","V10","V12","V19","V21")]
colnames(interesting_genes) = c("gene_id", "gene_chr","gene_start","gene_end","gene_snpid", "gene_snp_pos","gene_slope","gene_pvalue")
interesting_genes
head(ca_splicing)
Seon kromatiini kühmud ja geenid
interesting = dplyr::left_join(interesting_genes, ca_splicing, by = c("gene_snpid"="V4"))[1:9] %>% left_join(interesting_peaks, ., by=c('peak_snpid'='V1'))
Column `gene_snpid`/`V4` joining factors with different levels, coercing to character vectorColumn `peak_snpid`/`V1` joining factors with different levels, coercing to character vector
interesting = dplyr::select(interesting, -one_of('ctcf_chr','gene_chr', 'peak_snp_chr'))
Unknown columns: `ctcf_chr`
interesting$gene_id = substr(interesting$gene_id, 1, nchar("ENSG00000171735.contained")-10)
interesting
write.table(interesting, file = paste0(path, 'interesting.txt'), col.names = T, quote = F, row.names = F, append = F)
interesting = read.table(paste0(path, 'interesting.txt'), header = TRUE)
filtered = interesting[which(abs(interesting$peak_slope)>0.4 & abs(interesting$gene_slope)>0.4 & interesting$ca_pvalue<1e-4 & interesting$gene_pvalue<1e-4),]
filtered
ATAC
#proovid
ATAC_sample_metadata = read.table(paste0(path,'QC_measures/run_sample_accession_PhaseIII.txt'))
colnames(ATAC_sample_metadata) = c("sample_id", "genotype_id")
ATAC_sample_metadata["condition_name"] = rep("naive", dim(ATAC_sample_metadata)[1])
#genotüübid
vcf_file = readRDS(paste0(path, 'genotypes/Kumasaka_100_samples.merged.rds'))
ATAC_meta_df = read.table(paste0(path, 'ATAC_meta_df'), header = TRUE)
ATAC_peak_metadata = read.table(paste0(path,'ATAC_peak_metadata'), header = TRUE)
regions_df = unique(interesting[,c('peak_id', 'peak_chr','peak_start', 'peak_end','peak_snpid', 'peak_snp_pos', 'gene_id', 'peak_chr','gene_start', 'gene_end','gene_snpid','gene_snp_pos')])
regions_df
#rm(vcf_file,ATAC_counts)
RNA
RNA_sample_metadata = read.table("/gpfs/hpchome/a72094/hpc/datasets/controlled_access/SampleArcheology/studies/cleaned/GEUVADIS.tsv", header = TRUE)[,c("sample_id","genotype_id","condition")]
colnames(RNA_sample_metadata)[3] = "condition_name"
if (FALSE){
# RNA seq lugemite arv used for calculating library size
RNA_counts = read.table("/gpfs/hpchome/a72094/hpc/projects/RNAseq_pipeline/results/expression_matrices/featureCounts/GEUVADIS.tsv.gz", header = TRUE)
RNA_meta_df = wiggleplotrConstructMetadata(RNA_counts, RNA_sample_metadata, "/gpfs/hpc/home/a72094/projects/RNAseq_pipeline/processed/GEUVADIS/bigwig", bigWig_suffix = ".str1.bw", condition_name_levels = c("naive"))
rm(RNA_counts)
saveRDS(RNA_meta_df, paste0(path, 'RNA_meta_df'))
}
RNA_meta_df = readRDS(paste0(path, 'RNA_meta_df'))
RNA_meta_df
geenide annotatsioonid ja transkriptide annotatsioonid
if (FALSE){
gtf_df <- as.data.frame(rtracklayer::import(paste0(path, 'genotypes/Homo_sapiens.GRCh38.96.chr.gtf.gz')))
filtered_annotations = gtf_df[gtf_df$gene_id %in% regions_df$gene_id,]
filtered_annotations
rm(gtf_df)
saveRDS(filtered_annotations, paste0(path, 'filtered_annotations'))
}
filtered_annotations = readRDS(paste0(path, 'filtered_annotations'))
filtered_annotations
Koik geeni eksonid GRanges objektidena
find_peak_annotations = function(region_coords, chr, RNA_peak_metadata){
RNA_peak_annot = wiggleplotrExtractPeaks(region_coords, chrom = chr, RNA_peak_metadata)
RNA_peak_annot$peak_annot$transcript_id='RNA'
RNA_peak_annot$peak_annot$gene_id = 'RNA'
RNA_peak_annot$peak_annot$gene_name = 'RNA-seq'
names(RNA_peak_annot$peak_list) = 'RNA'
return(RNA_peak_annot)
}
Leian vcf failist caQTL juhtvariandile vastava genotuubi
library(GenomicRanges)
find_genotype = function(chr, pos){
SNP = GRanges(seqnames=chr, strand = c("*"), ranges = IRanges(start = pos-1, end = pos+1))
genotype = scanTabixDataFrame(paste0(path, 'genotypes/GEUVADIS_GRCh38_filtered.vcf.gz'), SNP, col_names = FALSE)[[1]]
#zgrep -m 1 "#CHROM" GEUVADIS_GRCh38_filtered.vcf.gz > vcf_genotype_id
#vim vcf_genotype_id delete #
colnames(genotype) = scan(paste0(path, '/genotypes/vcf_genotype_id'), character(), quote = "")
#unlink(paste0(path, '/genotypes/vcf_genotype_id'))
genotype[genotype=="0|0"]<-0
genotype[genotype=="1|0"]<-1
genotype[genotype=="0|1"]<-1
genotype[genotype=="1|1"]<-2
return(genotype)
}
find_RNA_track_data = function(genotype, chr, pos, RNA_meta_df){
# add colour group
colour_group = genotype[which(genotype$CHROM==chr & genotype$POS==pos), ] %>% select(10:454) %>% gather(., key= colnames(.), value=.[1,])
colnames(colour_group) = c('genotype_id', 'colour_group')
RNA_track_data = dplyr::left_join(RNA_meta_df, colour_group, by='genotype_id') %>% dplyr::mutate(track_id = "RNA-seq")
RNA_track_data[, 'colour_group'] = as.factor(RNA_track_data[, 'colour_group'])
return(RNA_track_data)
}
find_ATAC_track_data = function(vcf_file, ATAC_rs_id, ATAC_meta_df){
ATAC_colour_group = data.frame(genotype_id = names(vcf_file$genotypes[ATAC_rs_id,]), colour_group=vcf_file$genotypes[ATAC_rs_id,])
ATAC_track_data = dplyr::left_join(ATAC_meta_df, ATAC_colour_group, by='genotype_id') %>% dplyr::mutate(track_id = "ATAC-seq")
ATAC_track_data[, 'colour_group'] = as.factor(ATAC_track_data[, 'colour_group'])
return(ATAC_track_data)
}
peak_list = c('ATAC_peak_54976', 'ATAC_peak_177080')
gene_list = c('ENSG00000010219', 'ENSG00000173200')
peak_list = c('ATAC_peak_177080')
gene_list = c('ENSG00000173200')
regions_df = dplyr::filter(regions_df, regions_df$peak_id %in% peak_list)
regions_df
ATAC joonised
library(ggplot2)
for (i in 1:dim(regions_df)[1]){
ATAC_rs_id = regions_df[i, 'peak_snpid']
peak_id = regions_df[i, 'peak_id']
ATAC_region_coords=c(regions_df[i,'peak_start']-1000, regions_df[i,'peak_end']+1000)
chr = regions_df[i,'peak_chr']
pos = regions_df[i, 'peak_snp_pos']
gene_rs_id = regions_df[i, 'gene_snpid']
gene_id = regions_df[i, 'gene_id']
gene_region_coords = c(filtered_annotations[which(filtered_annotations$type=='gene' & filtered_annotations$gene_id ==gene_id),'start'], filtered_annotations[which(filtered_annotations$type=='gene' & filtered_annotations$gene_id ==gene_id),'end'])
RNA_peak_metadata = filtered_annotations[which(filtered_annotations$type=='exon' & filtered_annotations$gene_id==gene_id),c("seqnames", "start", "end", "strand")]
colnames(RNA_peak_metadata)[1]='chr'
genotype=find_genotype(chr, pos)
ATAC_peak_annot = wiggleplotrExtractPeaks(ATAC_region_coords, chrom = chr, ATAC_peak_metadata)
RNA_peak_annot = find_peak_annotations(gene_region_coords, chr, RNA_peak_metadata)
# add colour group
ATAC_track_data = find_ATAC_track_data(vcf_file, ATAC_rs_id, ATAC_meta_df)
RNA_track_data = find_RNA_track_data(genotype, chr, pos, RNA_meta_df)
#ainult need kromatiini kuhmud, mille juhtvariant on genotuubitud
if (sum(is.na(RNA_track_data$colour_group))<100){
ATAC_coverage = plotCoverage(exons = ATAC_peak_annot$peak_list, cdss = ATAC_peak_annot$peak_list, track_data = ATAC_track_data, rescale_introns = FALSE,
transcript_annotations = ATAC_peak_annot$peak_annot, fill_palette = getGenotypePalette(),
connect_exons = FALSE, transcript_label = FALSE, plot_fraction = 0.1, heights = c(0.7,0.3),
region_coords = ATAC_region_coords, return_subplots_list = TRUE, coverage_type = "line")
RNA_coverage = plotCoverage(exons = RNA_peak_annot$peak_list, cdss = RNA_peak_annot$peak_list, track_data = RNA_track_data, rescale_introns = TRUE,
transcript_annotations = RNA_peak_annot$peak_annot, fill_palette = getGenotypePalette(),
connect_exons = FALSE, transcript_label = FALSE, plot_fraction = 0.1, heights = c(0.7,0.3),
region_coords = gene_region_coords, return_subplots_list = TRUE, coverage_type = "line")
ATAC_plot = cowplot::plot_grid(ATAC_coverage$coverage_plot,
ATAC_coverage$tx_structure,
align = "v", nrow = 2, rel_heights = c(3, 1))
ATAC_plot
ggsave(paste0('/gpfs/hpchome/evelin95/plots/ca_splicing/',peak_id,'.pdf'), plot = ATAC_plot, width = 5, height = 4)
RNA_plot = cowplot::plot_grid(RNA_coverage$coverage_plot,
RNA_coverage$tx_structure,
align = "v", nrow = 2, rel_heights = c(3, 1))
ggsave(paste0('/gpfs/hpchome/evelin95/plots/ca_splicing/',gene_id,'.pdf'), plot = RNA_coverage$coverage_plot, width = 5, height = 2)
}
}
Read 454 items
Column `genotype_id` joining factor and character vector, coercing into character vectorbigWig column in track_data data.frame is a factor, coverting to a character vector.Column `sample_id` joining character vector and factor, coercing into character vector
uus = RNA_coverage$coverage_plot + scale_x_continuous(name="Kaugus regiooni algusest (bp)", limits=c(0, 3000))
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.
uus


ATAC_plot + annotate("text", x = 122647000, y = 0.5, label = "avatud kromatiin")

LS0tCnRpdGxlOiAiS3JvbWF0aWluaSBhdmF0dXNlIGphIHNwbGFpc3NpbWlzZSBzZW9zdGUgdmlzdWFsaXNlZXJpbWluZSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKYGBge3J9CnBhdGggPSAiL2dwZnMvaHBjaG9tZS9hNzIwOTQvcm9ja2V0L3Byb2plY3RzL2Nocm9tYXRpbl90b19zcGxpY2luZy8iCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgicmVhZHIiKQpsaWJyYXJ5KCJkZXZ0b29scyIpCmxpYnJhcnkoInJ0cmFja2xheWVyIikKbGlicmFyeSgid2lnZ2xlcGxvdHIiKQpsaWJyYXJ5KCJHZW5vbWljUmFuZ2VzIikKbGlicmFyeSgnUnNhbXRvb2xzJykKbGlicmFyeSgndGlkeXInKQpsb2FkX2FsbCgiL2dwZnMvcm9ja2V0L2hvbWUvYTcyMDk0L3Byb2plY3RzL2Nocm9tYXRpbl90b19zcGxpY2luZy9zZXFVdGlscy8iKQpgYGAKCgpTcGxhaXNzaW1pc2UgYW5kbWVkCmBgYHtyfQojZ2VlbmlkLCBtaWxsZWwgbGVpZHViIHNwbGFpc3MgUVRMCnNwbGljaW5nID0gcmVhZC50YWJsZShwYXN0ZTAocGF0aCwgInRhYml4L3R4cmV2aXNlLnNpZ25pZmljYW50LmNvbnRhaW5lZC5zb3J0ZWQudHh0Lmd6IikpCgojcjIgc2VvdHVkIHNwbGFzcyBqYSBjYSBsb29rdXN0ZSBwYWFyaWQKY2Ffc3BsaWNpbmcgPSByZWFkLnRhYmxlKHBhc3RlMChwYXRoLCAicmVzdWx0cy9yc3F1YXJlZDA4L2Nxbl9jb250YWluZWRfcnNxLnR4dCIpKQpgYGAKCktyb21hdGlpbmkgYXZhdHVzZSBhbmRtZWQKCkFsdXNla3MgcGVhdmFkIG9sZW1hIGtyb21hdGlpbmkgYXZhdHVzZSBrw7xobXVkLCBtaWxsZWwgbGVpZHViOgoxLiBzdGF0aXN0aWxpc2VsdCBvbHVsaW5lIGNhUVRMIDI1ODcyCjIuIGNhUVRMIG9uIHNlb3R1ZCBzcGxhaXNzIFFUTCdnYSAKCgpBbHVzdHVzZWtzIGxlaWFuIGvDtWlrIGvDvGhtdWQsIG1pcyB2YXN0YXZhZCBrcml0ZWVyaXVtaXRlbGUKYGBge3J9CmNhID0gcmVhZC50YWJsZShwYXN0ZTAocGF0aCwgJ3RhYml4L2Nxbl9wZXJtdXRhdGlvbnNfMTAwMDAwX3NpZ25pZmljYW50LnNvcnRlZC50eHQuZ3onKSkKY2FfaW50ZXJlc3RpbmdfcGVha3MgPSBjYVt3aGljaChjYSRWOCAlaW4lIGNhX3NwbGljaW5nJFYxKSxdCnJtKGNhKQpgYGAKCmBgYHtyfQppbnRlcmVzdGluZ19wZWFrcyA9IGRwbHlyOjpzZWxlY3QoY2FfaW50ZXJlc3RpbmdfcGVha3MsIGMoIlYxIiwgIlYyIiwgIlYzIiwgIlY0IiwgIlY4IiwgIlY5IiwgIlYxMCIsICJWMTciLCJWMTkiKSkKY29sbmFtZXMoaW50ZXJlc3RpbmdfcGVha3MpID0gYygicGVha19pZCIsInBlYWtfY2hyIiwgInBlYWtfc3RhcnQiLCAicGVha19lbmQiLCAicGVha19zbnBpZCIsICJwZWFrX3NucF9jaHIiLCAicGVha19zbnBfcG9zIiwgInBlYWtfc2xvcGUiLCAiY2FfcHZhbHVlIikKaW50ZXJlc3RpbmdfcGVha3MKYGBgCgoKR2VlbmlkLCBtaWxsZSBzcGxhaXNzaW1pbmUgb24gUjIgc2VvdHVkIGtyb21hdGlpbmkgYXZhdHVzZWdhCmBgYHtyfQppbnRlcmVzdGluZ19nZW5lcyA9IHNwbGljaW5nW3doaWNoKHNwbGljaW5nJFYxMCAlaW4lIGNhX3NwbGljaW5nJFY0KSxjKCJWMSIsICJWMiIsICJWMyIsIlY0IiwiVjEwIiwiVjEyIiwiVjE5IiwiVjIxIildCmNvbG5hbWVzKGludGVyZXN0aW5nX2dlbmVzKSA9IGMoImdlbmVfaWQiLCAiZ2VuZV9jaHIiLCJnZW5lX3N0YXJ0IiwiZ2VuZV9lbmQiLCJnZW5lX3NucGlkIiwgImdlbmVfc25wX3BvcyIsImdlbmVfc2xvcGUiLCJnZW5lX3B2YWx1ZSIpCmludGVyZXN0aW5nX2dlbmVzCmBgYAoKYGBge3J9CmhlYWQoY2Ffc3BsaWNpbmcpCmBgYAoKCgpTZW9uIGtyb21hdGlpbmkga8O8aG11ZCBqYSBnZWVuaWQKYGBge3J9CmludGVyZXN0aW5nID0gZHBseXI6OmxlZnRfam9pbihpbnRlcmVzdGluZ19nZW5lcywgY2Ffc3BsaWNpbmcsIGJ5ID0gYygiZ2VuZV9zbnBpZCI9IlY0IikpWzE6OV0gJT4lIGxlZnRfam9pbihpbnRlcmVzdGluZ19wZWFrcywgLiwgYnk9YygncGVha19zbnBpZCc9J1YxJykpCmludGVyZXN0aW5nID0gZHBseXI6OnNlbGVjdChpbnRlcmVzdGluZywgLW9uZV9vZignY3RjZl9jaHInLCdnZW5lX2NocicsICdwZWFrX3NucF9jaHInKSkKaW50ZXJlc3RpbmckZ2VuZV9pZCA9IHN1YnN0cihpbnRlcmVzdGluZyRnZW5lX2lkLCAxLCBuY2hhcigiRU5TRzAwMDAwMTcxNzM1LmNvbnRhaW5lZCIpLTEwKQppbnRlcmVzdGluZwpgYGAKCmBgYHtyfQp3cml0ZS50YWJsZShpbnRlcmVzdGluZywgZmlsZSA9IHBhc3RlMChwYXRoLCAnaW50ZXJlc3RpbmcudHh0JyksIGNvbC5uYW1lcyA9IFQsIHF1b3RlID0gRiwgcm93Lm5hbWVzID0gRiwgYXBwZW5kID0gRikKYGBgCgpgYGB7cn0KaW50ZXJlc3RpbmcgPSByZWFkLnRhYmxlKHBhc3RlMChwYXRoLCAnaW50ZXJlc3RpbmcudHh0JyksIGhlYWRlciA9IFRSVUUpCmBgYAoKYGBge3J9CmZpbHRlcmVkID0gaW50ZXJlc3Rpbmdbd2hpY2goYWJzKGludGVyZXN0aW5nJHBlYWtfc2xvcGUpPjAuNCAmIGFicyhpbnRlcmVzdGluZyRnZW5lX3Nsb3BlKT4wLjQgJiBpbnRlcmVzdGluZyRjYV9wdmFsdWU8MWUtNCAmIGludGVyZXN0aW5nJGdlbmVfcHZhbHVlPDFlLTQpLF0KZmlsdGVyZWQKYGBgCgoKIyBBVEFDCmBgYHtyfQojcHJvb3ZpZApBVEFDX3NhbXBsZV9tZXRhZGF0YSA9IHJlYWQudGFibGUocGFzdGUwKHBhdGgsJ1FDX21lYXN1cmVzL3J1bl9zYW1wbGVfYWNjZXNzaW9uX1BoYXNlSUlJLnR4dCcpKQpjb2xuYW1lcyhBVEFDX3NhbXBsZV9tZXRhZGF0YSkgPSBjKCJzYW1wbGVfaWQiLCAiZ2Vub3R5cGVfaWQiKQpBVEFDX3NhbXBsZV9tZXRhZGF0YVsiY29uZGl0aW9uX25hbWUiXSA9IHJlcCgibmFpdmUiLCBkaW0oQVRBQ19zYW1wbGVfbWV0YWRhdGEpWzFdKQpgYGAKCmBgYHtyfQojZ2Vub3TDvMO8YmlkCnZjZl9maWxlID0gcmVhZFJEUyhwYXN0ZTAocGF0aCwgJ2dlbm90eXBlcy9LdW1hc2FrYV8xMDBfc2FtcGxlcy5tZXJnZWQucmRzJykpCmBgYAoKCmBgYHtyfQpBVEFDX21ldGFfZGYgPSByZWFkLnRhYmxlKHBhc3RlMChwYXRoLCAnQVRBQ19tZXRhX2RmJyksIGhlYWRlciA9IFRSVUUpCkFUQUNfcGVha19tZXRhZGF0YSA9IHJlYWQudGFibGUocGFzdGUwKHBhdGgsJ0FUQUNfcGVha19tZXRhZGF0YScpLCBoZWFkZXIgPSBUUlVFKQpgYGAKCgpgYGB7cn0KcmVnaW9uc19kZiA9IHVuaXF1ZShpbnRlcmVzdGluZ1ssYygncGVha19pZCcsICdwZWFrX2NocicsJ3BlYWtfc3RhcnQnLCAncGVha19lbmQnLCdwZWFrX3NucGlkJywgJ3BlYWtfc25wX3BvcycsICdnZW5lX2lkJywgJ3BlYWtfY2hyJywnZ2VuZV9zdGFydCcsICdnZW5lX2VuZCcsJ2dlbmVfc25waWQnLCdnZW5lX3NucF9wb3MnKV0pCnJlZ2lvbnNfZGYKYGBgCgoKYGBge3J9CiNybSh2Y2ZfZmlsZSxBVEFDX2NvdW50cykKYGBgCgojIFJOQQpgYGB7cn0KUk5BX3NhbXBsZV9tZXRhZGF0YSA9IHJlYWQudGFibGUoIi9ncGZzL2hwY2hvbWUvYTcyMDk0L2hwYy9kYXRhc2V0cy9jb250cm9sbGVkX2FjY2Vzcy9TYW1wbGVBcmNoZW9sb2d5L3N0dWRpZXMvY2xlYW5lZC9HRVVWQURJUy50c3YiLCBoZWFkZXIgPSBUUlVFKVssYygic2FtcGxlX2lkIiwiZ2Vub3R5cGVfaWQiLCJjb25kaXRpb24iKV0KY29sbmFtZXMoUk5BX3NhbXBsZV9tZXRhZGF0YSlbM10gPSAiY29uZGl0aW9uX25hbWUiCmBgYAoKYGBge3J9CmlmIChGQUxTRSl7CiAgIyBSTkEgc2VxIGx1Z2VtaXRlIGFydiB1c2VkIGZvciBjYWxjdWxhdGluZyBsaWJyYXJ5IHNpemUKICBSTkFfY291bnRzID0gcmVhZC50YWJsZSgiL2dwZnMvaHBjaG9tZS9hNzIwOTQvaHBjL3Byb2plY3RzL1JOQXNlcV9waXBlbGluZS9yZXN1bHRzL2V4cHJlc3Npb25fbWF0cmljZXMvZmVhdHVyZUNvdW50cy9HRVVWQURJUy50c3YuZ3oiLCBoZWFkZXIgPSBUUlVFKQogIFJOQV9tZXRhX2RmID0gd2lnZ2xlcGxvdHJDb25zdHJ1Y3RNZXRhZGF0YShSTkFfY291bnRzLCBSTkFfc2FtcGxlX21ldGFkYXRhLCAiL2dwZnMvaHBjL2hvbWUvYTcyMDk0L3Byb2plY3RzL1JOQXNlcV9waXBlbGluZS9wcm9jZXNzZWQvR0VVVkFESVMvYmlnd2lnIiwgYmlnV2lnX3N1ZmZpeCA9ICIuc3RyMS5idyIsIGNvbmRpdGlvbl9uYW1lX2xldmVscyA9IGMoIm5haXZlIikpCiAgcm0oUk5BX2NvdW50cykKICBzYXZlUkRTKFJOQV9tZXRhX2RmLCBwYXN0ZTAocGF0aCwgJ1JOQV9tZXRhX2RmJykpCn0KYGBgCgpgYGB7cn0KUk5BX21ldGFfZGYgPSByZWFkUkRTKHBhc3RlMChwYXRoLCAnUk5BX21ldGFfZGYnKSkKUk5BX21ldGFfZGYKYGBgCgoKZ2VlbmlkZSBhbm5vdGF0c2lvb25pZCBqYSB0cmFuc2tyaXB0aWRlIGFubm90YXRzaW9vbmlkCmBgYHtyfQppZiAoRkFMU0UpewogIGd0Zl9kZiA8LSBhcy5kYXRhLmZyYW1lKHJ0cmFja2xheWVyOjppbXBvcnQocGFzdGUwKHBhdGgsICdnZW5vdHlwZXMvSG9tb19zYXBpZW5zLkdSQ2gzOC45Ni5jaHIuZ3RmLmd6JykpKQogIGZpbHRlcmVkX2Fubm90YXRpb25zID0gZ3RmX2RmW2d0Zl9kZiRnZW5lX2lkICVpbiUgcmVnaW9uc19kZiRnZW5lX2lkLF0KICBmaWx0ZXJlZF9hbm5vdGF0aW9ucwogIHJtKGd0Zl9kZikKICBzYXZlUkRTKGZpbHRlcmVkX2Fubm90YXRpb25zLCBwYXN0ZTAocGF0aCwgJ2ZpbHRlcmVkX2Fubm90YXRpb25zJykpCn0KYGBgCgoKYGBge3J9CmZpbHRlcmVkX2Fubm90YXRpb25zID0gcmVhZFJEUyhwYXN0ZTAocGF0aCwgJ2ZpbHRlcmVkX2Fubm90YXRpb25zJykpCmZpbHRlcmVkX2Fubm90YXRpb25zCmBgYAoKCktvaWsgZ2VlbmkgZWtzb25pZCBHUmFuZ2VzIG9iamVrdGlkZW5hCmBgYHtyfQpmaW5kX3BlYWtfYW5ub3RhdGlvbnMgPSBmdW5jdGlvbihyZWdpb25fY29vcmRzLCBjaHIsIFJOQV9wZWFrX21ldGFkYXRhKXsKICBSTkFfcGVha19hbm5vdCA9IHdpZ2dsZXBsb3RyRXh0cmFjdFBlYWtzKHJlZ2lvbl9jb29yZHMsIGNocm9tID0gY2hyLCBSTkFfcGVha19tZXRhZGF0YSkKICBSTkFfcGVha19hbm5vdCRwZWFrX2Fubm90JHRyYW5zY3JpcHRfaWQ9J1JOQScKICBSTkFfcGVha19hbm5vdCRwZWFrX2Fubm90JGdlbmVfaWQgPSAnUk5BJwogIFJOQV9wZWFrX2Fubm90JHBlYWtfYW5ub3QkZ2VuZV9uYW1lID0gJ1JOQS1zZXEnCiAgbmFtZXMoUk5BX3BlYWtfYW5ub3QkcGVha19saXN0KSA9ICdSTkEnCiAgcmV0dXJuKFJOQV9wZWFrX2Fubm90KQp9CmBgYAoKTGVpYW4gdmNmIGZhaWxpc3QgY2FRVEwganVodHZhcmlhbmRpbGUgdmFzdGF2YSBnZW5vdHV1YmkKYGBge3J9CmxpYnJhcnkoR2Vub21pY1JhbmdlcykKZmluZF9nZW5vdHlwZSA9IGZ1bmN0aW9uKGNociwgcG9zKXsKICBTTlAgPSBHUmFuZ2VzKHNlcW5hbWVzPWNociwgc3RyYW5kID0gYygiKiIpLCByYW5nZXMgPSBJUmFuZ2VzKHN0YXJ0ID0gcG9zLTEsIGVuZCA9IHBvcysxKSkKICBnZW5vdHlwZSA9IHNjYW5UYWJpeERhdGFGcmFtZShwYXN0ZTAocGF0aCwgJ2dlbm90eXBlcy9HRVVWQURJU19HUkNoMzhfZmlsdGVyZWQudmNmLmd6JyksIFNOUCwgY29sX25hbWVzID0gRkFMU0UpW1sxXV0KICAKICAjemdyZXAgLW0gMSAiI0NIUk9NIiBHRVVWQURJU19HUkNoMzhfZmlsdGVyZWQudmNmLmd6ID4gdmNmX2dlbm90eXBlX2lkCiAgI3ZpbSB2Y2ZfZ2Vub3R5cGVfaWQgZGVsZXRlICMKICAKICBjb2xuYW1lcyhnZW5vdHlwZSkgPSBzY2FuKHBhc3RlMChwYXRoLCAnL2dlbm90eXBlcy92Y2ZfZ2Vub3R5cGVfaWQnKSwgY2hhcmFjdGVyKCksIHF1b3RlID0gIiIpCiAgI3VubGluayhwYXN0ZTAocGF0aCwgJy9nZW5vdHlwZXMvdmNmX2dlbm90eXBlX2lkJykpCiAgCiAgZ2Vub3R5cGVbZ2Vub3R5cGU9PSIwfDAiXTwtMAogIGdlbm90eXBlW2dlbm90eXBlPT0iMXwwIl08LTEKICBnZW5vdHlwZVtnZW5vdHlwZT09IjB8MSJdPC0xCiAgZ2Vub3R5cGVbZ2Vub3R5cGU9PSIxfDEiXTwtMgogIAogIHJldHVybihnZW5vdHlwZSkKfQpgYGAKCgpgYGB7cn0KZmluZF9STkFfdHJhY2tfZGF0YSA9IGZ1bmN0aW9uKGdlbm90eXBlLCBjaHIsIHBvcywgUk5BX21ldGFfZGYpewogICMgYWRkIGNvbG91ciBncm91cAogIGNvbG91cl9ncm91cCA9IGdlbm90eXBlW3doaWNoKGdlbm90eXBlJENIUk9NPT1jaHIgJiBnZW5vdHlwZSRQT1M9PXBvcyksIF0gJT4lIHNlbGVjdCgxMDo0NTQpICU+JSBnYXRoZXIoLiwga2V5PSBjb2xuYW1lcyguKSwgdmFsdWU9LlsxLF0pCiAgY29sbmFtZXMoY29sb3VyX2dyb3VwKSA9IGMoJ2dlbm90eXBlX2lkJywgJ2NvbG91cl9ncm91cCcpCiAgCiAgUk5BX3RyYWNrX2RhdGEgPSBkcGx5cjo6bGVmdF9qb2luKFJOQV9tZXRhX2RmLCBjb2xvdXJfZ3JvdXAsIGJ5PSdnZW5vdHlwZV9pZCcpICU+JSBkcGx5cjo6bXV0YXRlKHRyYWNrX2lkID0gIlJOQS1zZXEiKQogIFJOQV90cmFja19kYXRhWywgJ2NvbG91cl9ncm91cCddID0gYXMuZmFjdG9yKFJOQV90cmFja19kYXRhWywgJ2NvbG91cl9ncm91cCddKQogIHJldHVybihSTkFfdHJhY2tfZGF0YSkKfQpgYGAKCmBgYHtyfQpmaW5kX0FUQUNfdHJhY2tfZGF0YSA9IGZ1bmN0aW9uKHZjZl9maWxlLCBBVEFDX3JzX2lkLCBBVEFDX21ldGFfZGYpewogIEFUQUNfY29sb3VyX2dyb3VwID0gZGF0YS5mcmFtZShnZW5vdHlwZV9pZCA9IG5hbWVzKHZjZl9maWxlJGdlbm90eXBlc1tBVEFDX3JzX2lkLF0pLCBjb2xvdXJfZ3JvdXA9dmNmX2ZpbGUkZ2Vub3R5cGVzW0FUQUNfcnNfaWQsXSkKICBBVEFDX3RyYWNrX2RhdGEgPSBkcGx5cjo6bGVmdF9qb2luKEFUQUNfbWV0YV9kZiwgQVRBQ19jb2xvdXJfZ3JvdXAsIGJ5PSdnZW5vdHlwZV9pZCcpICU+JSBkcGx5cjo6bXV0YXRlKHRyYWNrX2lkID0gIkFUQUMtc2VxIikKICBBVEFDX3RyYWNrX2RhdGFbLCAnY29sb3VyX2dyb3VwJ10gPSBhcy5mYWN0b3IoQVRBQ190cmFja19kYXRhWywgJ2NvbG91cl9ncm91cCddKQogIHJldHVybihBVEFDX3RyYWNrX2RhdGEpCn0KYGBgCgpgYGB7cn0KcGVha19saXN0ID0gYygnQVRBQ19wZWFrXzU0OTc2JywgJ0FUQUNfcGVha18xNzcwODAnKQpnZW5lX2xpc3QgPSBjKCdFTlNHMDAwMDAwMTAyMTknLCAnRU5TRzAwMDAwMTczMjAwJykKYGBgCgoKYGBge3J9CnBlYWtfbGlzdCA9IGMoJ0FUQUNfcGVha18xNzcwODAnKQpnZW5lX2xpc3QgPSBjKCdFTlNHMDAwMDAxNzMyMDAnKQpgYGAKCmBgYHtyfQpyZWdpb25zX2RmID0gZHBseXI6OmZpbHRlcihyZWdpb25zX2RmLCByZWdpb25zX2RmJHBlYWtfaWQgJWluJSBwZWFrX2xpc3QpCnJlZ2lvbnNfZGYKYGBgCgoKQVRBQyBqb29uaXNlZApgYGB7cn0KbGlicmFyeShnZ3Bsb3QyKQoKCmZvciAoaSBpbiAxOmRpbShyZWdpb25zX2RmKVsxXSl7CiAgQVRBQ19yc19pZCA9IHJlZ2lvbnNfZGZbaSwgJ3BlYWtfc25waWQnXQogIHBlYWtfaWQgPSByZWdpb25zX2RmW2ksICdwZWFrX2lkJ10KICBBVEFDX3JlZ2lvbl9jb29yZHM9YyhyZWdpb25zX2RmW2ksJ3BlYWtfc3RhcnQnXS0xMDAwLCByZWdpb25zX2RmW2ksJ3BlYWtfZW5kJ10rMTAwMCkKICBjaHIgPSByZWdpb25zX2RmW2ksJ3BlYWtfY2hyJ10KICBwb3MgPSByZWdpb25zX2RmW2ksICdwZWFrX3NucF9wb3MnXQogIAogIGdlbmVfcnNfaWQgPSByZWdpb25zX2RmW2ksICdnZW5lX3NucGlkJ10KICBnZW5lX2lkID0gcmVnaW9uc19kZltpLCAnZ2VuZV9pZCddCiAgZ2VuZV9yZWdpb25fY29vcmRzID0gYyhmaWx0ZXJlZF9hbm5vdGF0aW9uc1t3aGljaChmaWx0ZXJlZF9hbm5vdGF0aW9ucyR0eXBlPT0nZ2VuZScgJiBmaWx0ZXJlZF9hbm5vdGF0aW9ucyRnZW5lX2lkID09Z2VuZV9pZCksJ3N0YXJ0J10sIGZpbHRlcmVkX2Fubm90YXRpb25zW3doaWNoKGZpbHRlcmVkX2Fubm90YXRpb25zJHR5cGU9PSdnZW5lJyAmIGZpbHRlcmVkX2Fubm90YXRpb25zJGdlbmVfaWQgPT1nZW5lX2lkKSwnZW5kJ10pCiAgCiAgCiAgUk5BX3BlYWtfbWV0YWRhdGEgPSBmaWx0ZXJlZF9hbm5vdGF0aW9uc1t3aGljaChmaWx0ZXJlZF9hbm5vdGF0aW9ucyR0eXBlPT0nZXhvbicgJiBmaWx0ZXJlZF9hbm5vdGF0aW9ucyRnZW5lX2lkPT1nZW5lX2lkKSxjKCJzZXFuYW1lcyIsICJzdGFydCIsICJlbmQiLCAic3RyYW5kIildCiAgY29sbmFtZXMoUk5BX3BlYWtfbWV0YWRhdGEpWzFdPSdjaHInCiAgZ2Vub3R5cGU9ZmluZF9nZW5vdHlwZShjaHIsIHBvcykKICAKICBBVEFDX3BlYWtfYW5ub3QgPSB3aWdnbGVwbG90ckV4dHJhY3RQZWFrcyhBVEFDX3JlZ2lvbl9jb29yZHMsIGNocm9tID0gY2hyLCBBVEFDX3BlYWtfbWV0YWRhdGEpCiAgUk5BX3BlYWtfYW5ub3QgPSBmaW5kX3BlYWtfYW5ub3RhdGlvbnMoZ2VuZV9yZWdpb25fY29vcmRzLCBjaHIsIFJOQV9wZWFrX21ldGFkYXRhKQogIAogICMgYWRkIGNvbG91ciBncm91cAogIEFUQUNfdHJhY2tfZGF0YSA9IGZpbmRfQVRBQ190cmFja19kYXRhKHZjZl9maWxlLCBBVEFDX3JzX2lkLCBBVEFDX21ldGFfZGYpCiAgUk5BX3RyYWNrX2RhdGEgPSBmaW5kX1JOQV90cmFja19kYXRhKGdlbm90eXBlLCBjaHIsIHBvcywgUk5BX21ldGFfZGYpCiAgCiAgCiAgI2FpbnVsdCBuZWVkIGtyb21hdGlpbmkga3VobXVkLCBtaWxsZSBqdWh0dmFyaWFudCBvbiBnZW5vdHV1Yml0dWQKICBpZiAoc3VtKGlzLm5hKFJOQV90cmFja19kYXRhJGNvbG91cl9ncm91cCkpPDEwMCl7CiAgICAKICAgIEFUQUNfY292ZXJhZ2UgPSBwbG90Q292ZXJhZ2UoZXhvbnMgPSBBVEFDX3BlYWtfYW5ub3QkcGVha19saXN0LCBjZHNzID0gQVRBQ19wZWFrX2Fubm90JHBlYWtfbGlzdCwgdHJhY2tfZGF0YSA9IEFUQUNfdHJhY2tfZGF0YSwgcmVzY2FsZV9pbnRyb25zID0gRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zY3JpcHRfYW5ub3RhdGlvbnMgPSBBVEFDX3BlYWtfYW5ub3QkcGVha19hbm5vdCwgZmlsbF9wYWxldHRlID0gZ2V0R2Vub3R5cGVQYWxldHRlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdF9leG9ucyA9IEZBTFNFLCB0cmFuc2NyaXB0X2xhYmVsID0gRkFMU0UsIHBsb3RfZnJhY3Rpb24gPSAwLjEsIGhlaWdodHMgPSBjKDAuNywwLjMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpb25fY29vcmRzID0gQVRBQ19yZWdpb25fY29vcmRzLCByZXR1cm5fc3VicGxvdHNfbGlzdCA9IFRSVUUsIGNvdmVyYWdlX3R5cGUgPSAibGluZSIpCiAgICAKICAgIFJOQV9jb3ZlcmFnZSA9IHBsb3RDb3ZlcmFnZShleG9ucyA9IFJOQV9wZWFrX2Fubm90JHBlYWtfbGlzdCwgY2RzcyA9IFJOQV9wZWFrX2Fubm90JHBlYWtfbGlzdCwgdHJhY2tfZGF0YSA9IFJOQV90cmFja19kYXRhLCByZXNjYWxlX2ludHJvbnMgPSBUUlVFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmFuc2NyaXB0X2Fubm90YXRpb25zID0gUk5BX3BlYWtfYW5ub3QkcGVha19hbm5vdCwgZmlsbF9wYWxldHRlID0gZ2V0R2Vub3R5cGVQYWxldHRlKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdF9leG9ucyA9IEZBTFNFLCB0cmFuc2NyaXB0X2xhYmVsID0gRkFMU0UsIHBsb3RfZnJhY3Rpb24gPSAwLjEsIGhlaWdodHMgPSBjKDAuNywwLjMpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpb25fY29vcmRzID0gZ2VuZV9yZWdpb25fY29vcmRzLCByZXR1cm5fc3VicGxvdHNfbGlzdCA9IFRSVUUsIGNvdmVyYWdlX3R5cGUgPSAibGluZSIpCiAgICAKICAgIEFUQUNfcGxvdCA9IGNvd3Bsb3Q6OnBsb3RfZ3JpZChBVEFDX2NvdmVyYWdlJGNvdmVyYWdlX3Bsb3QsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFUQUNfY292ZXJhZ2UkdHhfc3RydWN0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduID0gInYiLCBucm93ID0gMiwgcmVsX2hlaWdodHMgPSBjKDMsIDEpKQogICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgQVRBQ19wbG90CiAgICBnZ3NhdmUocGFzdGUwKCcvZ3Bmcy9ocGNob21lL2V2ZWxpbjk1L3Bsb3RzL2NhX3NwbGljaW5nLycscGVha19pZCwnLnBkZicpLCBwbG90ID0gQVRBQ19wbG90LCB3aWR0aCA9IDUsIGhlaWdodCA9IDQpCiAgICAKICAgIFJOQV9wbG90ID0gY293cGxvdDo6cGxvdF9ncmlkKFJOQV9jb3ZlcmFnZSRjb3ZlcmFnZV9wbG90LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSTkFfY292ZXJhZ2UkdHhfc3RydWN0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsaWduID0gInYiLCBucm93ID0gMiwgcmVsX2hlaWdodHMgPSBjKDMsIDEpKQogICAgCiAgICAKICAgIGdnc2F2ZShwYXN0ZTAoJy9ncGZzL2hwY2hvbWUvZXZlbGluOTUvcGxvdHMvY2Ffc3BsaWNpbmcvJyxnZW5lX2lkLCcucGRmJyksIHBsb3QgPSBSTkFfY292ZXJhZ2UkY292ZXJhZ2VfcGxvdCwgd2lkdGggPSA1LCBoZWlnaHQgPSAyKQogICAgICAKICB9CiAgCn0KYGBgCgoKYGBge3J9CnV1cyA9IFJOQV9jb3ZlcmFnZSRjb3ZlcmFnZV9wbG90ICArIHNjYWxlX3hfY29udGludW91cyhuYW1lPSJLYXVndXMgcmVnaW9vbmkgYWxndXNlc3QgKGJwKSIsIGxpbWl0cz1jKDAsIDMwMDApKQp1dXMKYGBgCgpgYGB7cn0KUk5BX2NvdmVyYWdlJHR4X3N0cnVjdHVyZQoKYGBgCgpgYGB7cn0KQVRBQ19wbG90ICsgYW5ub3RhdGUoInRleHQiLCB4ID0gMTIyNjQ3MDAwLCB5ID0gMC41LCBsYWJlbCA9ICJhdmF0dWQga3JvbWF0aWluIikKYGBgCgo=